package org.openfdtd.core3d;

import java.util.Iterator;
import java.util.ArrayList;
import javax.media.j3d.Shape3D;
import javax.media.j3d.LineArray;
import javax.media.j3d.Appearance;
import javax.media.j3d.BranchGroup;
import javax.media.j3d.TriangleArray;

/**
 *
 * @author Dorian C. Langbeck
 */
public class Surface extends BranchGroup implements Iterable<Vertex> {
    protected Edge[] edges;
    protected LineArray edgeGeometry;
    protected TriangleArray faceGeometry;
    protected ArrayList<Vertex> vertexes;
    protected SurfaceProperties properties;

    public Surface(double[] coords) {
        int size = coords.length >= 12 ? 4 : (coords.length >= 9 ? 3 : 0);
        if (size == 0)
            throw new IllegalArgumentException();

        edges = new Edge[size];
        vertexes = new ArrayList<Vertex>(size);
        double[] td = new double[3];
        for (int i = 0; i < size; i++) {
            System.arraycopy(coords, i * 3, td, 0, 3);
            vertexes.add(new Vertex(td));
        }

        int i = 0;
        for (; i < size - 1; i++)
            edges[i] = new Edge(vertexes.get(i), vertexes.get(i + 1));

        edges[i] = new Edge(vertexes.get(i), vertexes.get(0));

        faceGeometry = Util.buildSurfaceGeometry(vertexes.toArray(new Vertex[0]));
        addChild(Util.enableWrite(new Shape3D(Util.enableWrite(faceGeometry))));

        edgeGeometry = Util.buildEdgeGeometry(edges);
//        edgeGeometry = Util.buildEdgeGeometry(vertexes.toArray(new Vertex[0]));
        addChild(Util.enableWrite(new Shape3D(edgeGeometry)));
    }

    void update() {
        Util.updateSurfaceGeometry(faceGeometry, vertexes.toArray(new Vertex[0]));
//        Util.updateEdgeGeometry(edgeGeometry, vertexes.toArray(new Vertex[0]));
        Util.updateEdgeGeometry(edgeGeometry, edges);
    }

    public Vertex[] getVertexes() {
        return (Vertex[]) vertexes.toArray();
    }

    void setAppearance(Appearance app) {
        Util.changeAppearance(this, app);
    }

    public Edge[] getEdges() {
        return edges;
    }

    public int totalEdges() {
        return edges.length;
    }

    public void setProperties(SurfaceProperties prop) {
        properties = prop;
    }

    public SurfaceProperties getProperties() {
        return properties;
    }

    public Iterator<Vertex> iterator() {
        return vertexes.iterator();
    }
}
